from Function import *

class extended_Rosenbrock(Function):
    def f(self,vec):
        n = vec.shape[0]-1
        ans = 0
        for i in range(n):
            ans += 100*(vec[i+1,0]-vec[i,0]**2)**2+(1-vec[i,0])**2
        return ans

class Powell(Function):
    def f(self,vec):
        return (vec[0,0]+10*vec[1,0])**2+5*(vec[2,0]-vec[3,0])**2+(vec[1,0]-2*vec[2,0])**4+10*(vec[0,0]-vec[3,0])**4

F1 = extended_Rosenbrock()
F2 = Powell()
for i in [6,8,10]: 
    x0 = np.zeros((i,1))
    ans = np.zeros((i,1))
    for j in range(i//2):
        x0[2*j,0] = -1.2
        ans[2*j,0] = 1
        x0[2*j+1,0] = 1
        ans[2*j+1,0] = 1
    
    print("For Extended Rosenbrock function size n =",i)
    X = BFGS_Method(F1,x0)
    print(X)
    print("with error:",norm(X-ans))
x0 = np.array([[3.0],[-1.0],[0.0],[1.0]])
ans = np.array([[0.0],[0.0],[0.0],[0.0]])

print("For Powell function:")
X = BFGS_Method(F2,x0)
print(X)
print("with error:",norm(X))
